package com.ruoyi.project.manage.invest.service.impl;

import java.math.BigDecimal;
import java.util.List;

import com.ruoyi.common.constant.ProjectConstants;
import com.ruoyi.common.constant.UserConstants;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.security.ShiroUtils;
import com.ruoyi.project.manage.approveLog.domain.ApproveLog;
import com.ruoyi.project.manage.approveLog.mapper.ApproveLogMapper;
import com.ruoyi.project.manage.detail.domain.ProjectInvestDetail;
import com.ruoyi.project.manage.detail.mapper.ProjectInvestDetailMapper;
import com.ruoyi.project.manage.project.domain.Project;
import com.ruoyi.project.manage.project.mapper.ProjectMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.ruoyi.project.manage.invest.mapper.ProjectInvestMapper;
import com.ruoyi.project.manage.invest.domain.ProjectInvest;
import com.ruoyi.project.manage.invest.service.IProjectInvestService;
import com.ruoyi.common.utils.text.Convert;
import org.springframework.transaction.annotation.Transactional;

import javax.xml.soap.Detail;

/**
 * 资金落实记录Service业务层处理
 * 
 * @author fangkun
 * @date 2022-03-28
 */
@Service
@Transactional
public class ProjectInvestServiceImpl implements IProjectInvestService 
{
    @Autowired
    private ProjectInvestMapper projectInvestMapper;
    @Autowired
    private ProjectMapper projectMapper;
    @Autowired
    private ApproveLogMapper approveLogMapper;
    @Autowired
    private ProjectInvestDetailMapper investDetailMapper;

    /**
     * 查询资金落实记录
     * 
     * @param projectInvestId 资金落实记录主键
     * @return 资金落实记录
     */
    @Override
    public ProjectInvest selectProjectInvestByProjectInvestId(Long projectInvestId)
    {
        return projectInvestMapper.selectProjectInvestByProjectInvestId(projectInvestId);
    }

    /**
     * 查询资金落实记录列表
     * 
     * @param projectInvest 资金落实记录
     * @return 资金落实记录
     */
    @Override
    public List<ProjectInvest> selectProjectInvestList(ProjectInvest projectInvest)
    {
        return projectInvestMapper.selectProjectInvestList(projectInvest);
    }

    /**
     * 新增资金落实记录
     * 
     * @param projectInvest 资金落实记录
     * @return 结果
     */
    @Override
    public int insertProjectInvest(ProjectInvest projectInvest)
    {
        Project project = new Project();
        project.setProjectId(projectInvest.getProjectId());
        project.setInvestStatus(ProjectConstants.APPROVAL_UNSUBMIT);
        project.setTotalInvest(projectInvest.getTotalInvest());
        project.setDoneInvest(projectInvest.getDoneInvest());
        project.setActualInvest(projectInvest.getActualInvest());
        project.setPlanInvest(projectInvest.getPlanInvest());
        project.setFundDemand(projectInvest.getFundDemand());
        projectMapper.updateProject(project);

        // 查询是否存在
        ProjectInvest param = new ProjectInvest();
        param.setProjectId(projectInvest.getProjectId());
        param.setStatus(UserConstants.NORMAL);


        projectInvest.setInvestStatus(ProjectConstants.APPROVAL_UNSUBMIT);
        projectInvest.setStatus(UserConstants.NORMAL);
        projectInvest.setCreateTime(DateUtils.getNowDate());
        projectInvest.setCreateBy(ShiroUtils.getSysUser().getUserName());
        projectInvest.setUpdateTime(DateUtils.getNowDate());
        projectInvest.setUpdateBy(ShiroUtils.getSysUser().getUserName());
        return projectInvestMapper.insertProjectInvest(projectInvest);
    }

    /**
     * 修改资金落实记录
     * 
     * @param projectInvest 资金落实记录
     * @return 结果
     */
    @Override
    public int updateProjectInvest(ProjectInvest projectInvest)
    {
        Project project = new Project();
        project.setProjectId(projectInvest.getProjectId());
        project.setInvestStatus(ProjectConstants.APPROVAL_UNSUBMIT);
        project.setTotalInvest(projectInvest.getTotalInvest());

        project.setActualInvest(projectInvest.getActualInvest());
        project.setPlanInvest(projectInvest.getPlanInvest());
        project.setFundDemand(projectInvest.getFundDemand());
        project.setUpdateTime(DateUtils.getNowDate());
        project.setUpdateBy(ShiroUtils.getSysUser().getUserName());

        List<ProjectInvestDetail> investDetails = projectInvest.getInvestDetails();
        if (investDetails != null && investDetails.size() > 0) {
            for (ProjectInvestDetail investDetail : investDetails) {
                investDetail.setUpdateTime(DateUtils.getNowDate());
                investDetail.setUpdateBy(ShiroUtils.getSysUser().getUserName());

                if (investDetail.getProjectInvestDetailId() != null && investDetail.getProjectInvestDetailId() > 0) {
                    // 此时是更新
                    investDetailMapper.updateProjectInvestDetail(investDetail);
                } else {
                    // 插入
                    investDetail.setProjectId(projectInvest.getProjectId());
                    investDetail.setStatus(UserConstants.NORMAL);
                    investDetail.setCreateTime(DateUtils.getNowDate());
                    investDetail.setCreateBy(ShiroUtils.getSysUser().getUserName());
                    investDetailMapper.insertProjectInvestDetail(investDetail);
                }
            }
        }
        // 计算总投资
        ProjectInvestDetail param = new ProjectInvestDetail();
        param.setProjectId(projectInvest.getProjectId());
        param.setStatus(UserConstants.NORMAL);
        List<ProjectInvestDetail> projectInvestDetails = investDetailMapper.selectProjectInvestDetailList(param);
        double sum = projectInvestDetails.stream().filter(detail -> detail.getDoneInvest() != null).mapToDouble(detail -> detail.getDoneInvest().doubleValue()).sum();
        project.setDoneInvest(new BigDecimal(sum));

        return projectMapper.updateProject(project);
    }

    @Override
    public int submit(int projectId) {
        Project project = projectMapper.selectProjectByProjectId(Long.valueOf(projectId));

        if (project == null) {
            throw new ServiceException("指定项目不存在！");
        }

        if (ProjectConstants.APPROVAL_AGREE == project.getInvestStatus() || ProjectConstants.APPROVAL_SUBMIT == project.getInvestStatus()) {
            throw new ServiceException("指定项目投资建设资金情况已经提交！");
        }

        // 审批流转记录
        ApproveLog approveLog = new ApproveLog();
        approveLog.setEntityType(ProjectConstants.APPROVAL_TYPE_INVEST);
        approveLog.setEntityId(project.getProjectId());
        approveLog.setApproveResult(ProjectConstants.APPROVAL_SUBMIT);
        approveLog.setRemark("发起审核");
        approveLog.setCreateTime(DateUtils.getNowDate());
        approveLog.setCreateBy("录入员:" + ShiroUtils.getSysUser().getUserName());
        approveLog.setUpdateTime(DateUtils.getNowDate());
        approveLog.setUpdateBy(ShiroUtils.getLoginName());
        approveLogMapper.insertApproveLog(approveLog);

        project.setInvestStatus(ProjectConstants.APPROVAL_SUBMIT);
        project.setUpdateTime(DateUtils.getNowDate());
        project.setUpdateBy(ShiroUtils.getLoginName());
        return projectMapper.updateProject(project);
    }

    @Override
    public int withdraw(int projectId) {
        Project project = projectMapper.selectProjectByProjectId(Long.valueOf(projectId));

        if (project == null) {
            throw new ServiceException("指定项目不存在！");
        }

        if (ProjectConstants.APPROVAL_SUBMIT != project.getInvestStatus()) {
            throw new ServiceException("指定项目投资建设资金情况状态不能撤回！");
        }

        // 审批流转记录
        ApproveLog approveLog = new ApproveLog();
        approveLog.setEntityType(ProjectConstants.APPROVAL_TYPE_INVEST);
        approveLog.setEntityId(project.getProjectId());
        approveLog.setApproveResult(ProjectConstants.APPROVAL_UNSUBMIT);
        approveLog.setRemark("撤回");
        approveLog.setCreateTime(DateUtils.getNowDate());
        approveLog.setCreateBy("录入员:" + ShiroUtils.getSysUser().getUserName());
        approveLog.setUpdateTime(DateUtils.getNowDate());
        approveLog.setUpdateBy(ShiroUtils.getLoginName());
        approveLogMapper.insertApproveLog(approveLog);

        project.setInvestStatus(ProjectConstants.APPROVAL_UNSUBMIT);
        project.setUpdateTime(DateUtils.getNowDate());
        project.setUpdateBy(ShiroUtils.getLoginName());
        return projectMapper.updateProject(project);
    }

    @Override
    public int reject(Project project) {
        Project projectOld = projectMapper.selectProjectByProjectId(project.getProjectId());

        if (projectOld == null) {
            throw new ServiceException("指定项目不存在！");
        }

        if (ProjectConstants.APPROVAL_SUBMIT != projectOld.getInvestStatus()) {
            throw new ServiceException("指定项目投资建设资金情况不是上报状态！");
        }

        // 审批流转记录
        ApproveLog approveLog = new ApproveLog();
        approveLog.setEntityType(ProjectConstants.APPROVAL_TYPE_INVEST);
        approveLog.setEntityId(project.getProjectId());
        approveLog.setApproveResult(ProjectConstants.APPROVAL_REJECT);
        approveLog.setRemark("驳回");
        approveLog.setApproveComment(project.getRejectReason());
        approveLog.setCreateTime(DateUtils.getNowDate());
        approveLog.setCreateBy("审核员:" + ShiroUtils.getSysUser().getUserName());
        approveLog.setUpdateTime(DateUtils.getNowDate());
        approveLog.setUpdateBy(ShiroUtils.getLoginName());
        approveLogMapper.insertApproveLog(approveLog);

        project.setInvestStatus(ProjectConstants.APPROVAL_REJECT);
        project.setUpdateTime(DateUtils.getNowDate());
        project.setUpdateBy(ShiroUtils.getLoginName());
        return projectMapper.updateProject(project);
    }

    @Override
    public int agree(int projectId) {
        Project project = projectMapper.selectProjectByProjectId(Long.valueOf(projectId));

        if (project == null) {
            throw new ServiceException("指定项目不存在！");
        }

        if (ProjectConstants.APPROVAL_SUBMIT != project.getInvestStatus()) {
            throw new ServiceException("指定项目投资建设资金情况状态不能入库！");
        }

        // 审批流转记录
        ApproveLog approveLog = new ApproveLog();
        approveLog.setEntityType(ProjectConstants.APPROVAL_TYPE_INVEST);
        approveLog.setEntityId(project.getProjectId());
        approveLog.setApproveResult(ProjectConstants.APPROVAL_AGREE);
        approveLog.setRemark("审核通过");
        approveLog.setCreateTime(DateUtils.getNowDate());
        approveLog.setCreateBy("审核员:" + ShiroUtils.getSysUser().getUserName());
        approveLog.setUpdateTime(DateUtils.getNowDate());
        approveLog.setUpdateBy(ShiroUtils.getLoginName());
        approveLogMapper.insertApproveLog(approveLog);

        // 插入资金记录
        ProjectInvest projectInvest = new ProjectInvest();
        projectInvest.setProjectId(project.getProjectId());

        projectInvest.setTotalInvest(project.getTotalInvest());
        projectInvest.setDoneInvest(project.getDoneInvest());
        projectInvest.setActualInvest(project.getActualInvest());
        projectInvest.setPlanInvest(project.getPlanInvest());
        projectInvest.setFundDemand(project.getFundDemand());

        projectInvest.setInvestStatus(ProjectConstants.APPROVAL_AGREE);
        projectInvest.setStatus(UserConstants.NORMAL);
        projectInvest.setCreateTime(DateUtils.getNowDate());
        projectInvest.setCreateBy(ShiroUtils.getSysUser().getUserName());
        projectInvest.setUpdateTime(DateUtils.getNowDate());
        projectInvest.setUpdateBy(ShiroUtils.getSysUser().getUserName());
        projectInvestMapper.insertProjectInvest(projectInvest);

        // 设置资金状态
        project.setInvestStatus(ProjectConstants.APPROVAL_AGREE);
        project.setUpdateTime(DateUtils.getNowDate());
        project.setUpdateBy(ShiroUtils.getLoginName());
        return projectMapper.updateProject(project);
    }

    /**
     * 批量删除资金落实记录
     * 
     * @param projectInvestIds 需要删除的资金落实记录主键
     * @return 结果
     */
    @Override
    public int deleteProjectInvestByProjectInvestIds(String projectInvestIds)
    {
        return projectInvestMapper.deleteProjectInvestByProjectInvestIds(Convert.toStrArray(projectInvestIds));
    }

    /**
     * 删除资金落实记录信息
     * 
     * @param projectInvestId 资金落实记录主键
     * @return 结果
     */
    @Override
    public int deleteProjectInvestByProjectInvestId(Long projectInvestId)
    {
        return projectInvestMapper.deleteProjectInvestByProjectInvestId(projectInvestId);
    }
}
